package com.lin.manager.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lin.manager.common.ex.BizException;
import com.lin.manager.common.req.QueryPage;
import com.lin.manager.common.resp.DataPage;
import com.lin.manager.system.dao.SysRoleDao;
import com.lin.manager.system.entity.SysRoleEntity;
import com.lin.manager.system.entity.SysRoleMenuEntity;
import com.lin.manager.login.model.vo.LoginUserVo;
import com.lin.manager.system.service.SysRoleMenuService;
import com.lin.manager.system.service.SysRoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @作者: 林江
 * @创建时间: 2024/3/12
 * @功能:
 */
@Slf4j
@Service
public class SysRoleServiceImpl implements SysRoleService {
    @Autowired
    private SysRoleDao sysRoleDao;
    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Override
    public DataPage<SysRoleEntity> listPage(QueryPage page) {
        LambdaQueryWrapper<SysRoleEntity> wrapper = new QueryWrapper<SysRoleEntity>()
                .lambda()
                .like(StringUtils.isNotBlank(page.getKey()), SysRoleEntity::getRcode, page.getKey());

        Page<SysRoleEntity> selectPage = sysRoleDao.selectPage(new Page<>(page.getPageNum(), page.getPageSize()), wrapper);
        return DataPage.<SysRoleEntity>builder().page(selectPage).build();
    }

    @Override
    public List<SysRoleEntity> list(QueryPage page) {
        LambdaQueryWrapper<SysRoleEntity> wrapper = new QueryWrapper<SysRoleEntity>()
                .lambda()
                .like(StringUtils.isNotBlank(page.getKey()), SysRoleEntity::getRcode, page.getKey());

        return sysRoleDao.selectList(wrapper);
    }

    @Override
    public void add(SysRoleEntity sysRole) {
        checkCode(sysRole.getId(), sysRole.getRcode());
        sysRoleDao.insert(sysRole);
    }

    @Override
    public void update(SysRoleEntity sysRole) {
        checkCode(sysRole.getId(), sysRole.getRcode());
        sysRoleDao.updateById(sysRole);
    }


    @Override
    public void del(Integer id) {
        sysRoleDao.deleteById(id);
        sysRoleDao.deleteByRoleId(id);
        sysRoleMenuService.deleteByRoleId(id);
    }

    @Override
    public List<Integer> relative(Integer roleId) {
        List<SysRoleMenuEntity> roleMenus = sysRoleMenuService.findByRoleId(roleId);
        return roleMenus.stream().map(SysRoleMenuEntity::getMenuId).collect(Collectors.toList());
    }

    @Override
    public void binding(Integer roleId, List<Integer> menuIds) {
        // 删除权限
        sysRoleMenuService.deleteByRoleId(roleId);

        List<SysRoleMenuEntity> roleMenus = menuIds.stream().map(menuId -> {
            SysRoleMenuEntity roleMenu = new SysRoleMenuEntity();
            roleMenu.setRoleId(roleId);
            roleMenu.setMenuId(menuId);
            return roleMenu;
        }).collect(Collectors.toList());

        sysRoleMenuService.binding(roleMenus);
    }

    @Override
    public LoginUserVo findLoginRoleByRoleIds(List<Integer> roleIds) {
        if (roleIds.size() > 0) {
            List<SysRoleEntity> sysRoleEntities = sysRoleDao.selectList(new LambdaQueryWrapper<SysRoleEntity>().in(SysRoleEntity::getId, roleIds));
            // 获取当前所有角色绑定的权限
            LoginUserVo loginUserVo = sysRoleMenuService.findLoginMenuByRoleIds(roleIds);
            loginUserVo.setRoles(sysRoleEntities.stream().map(SysRoleEntity::getRcode).collect(Collectors.toList()));
            return loginUserVo;
        }
        return new LoginUserVo();
    }

    @Override
    public List<SysRoleEntity> findRoleByUserId(String userId) {
        return sysRoleDao.findRoleByUserId(userId);
    }

    /**
     * 角色编码必须唯一
     *
     * @param id
     * @param rcode
     */
    private void checkCode(Long id, String rcode) {
        LambdaQueryWrapper<SysRoleEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleEntity::getRcode, rcode);
        if (id != null) {
            wrapper.ne(SysRoleEntity::getId, id);
        }
        Long count = sysRoleDao.selectCount(wrapper);
        if (count > 0) {
            throw new BizException("角色编码重复，请重新设置");
        }
    }
}
